from rest_framework import serializers
from django_redis import get_redis_connection
from redis import RedisError
import logging

# 创建日志输出对象
logger = logging.getLogger('django')


class ImageCodeCheckSerializer(serializers.Serializer):
    """图片验证码校验序列化器"""
    # 传入要校验的字段，名字要和字段名字一致
    image_code_id = serializers.UUIDField()
    text = serializers.CharField(max_length=4, min_length=4)

    def validate(self, attrs):
        """对比服务器验证码与用户输入的验证码"""

        # 取出经过字段校验后的数据
        image_code_id = attrs['image_code_id']
        text = attrs['text']

        # 根据图片验证码id取出redis中存储的真实验证码
        redis_conn = get_redis_connection('verify_codes')
        image_code_server = redis_conn.get('img_%s' % image_code_id)

        # 判断验证码是否存在
        if image_code_server is None:
            raise serializers.ValidationError("无效图片验证码")

        # 删除redis中图片验证码 防止暴力测试
        # 在获取到验证码之后，对比验证码之前删除
        try:
            redis_conn.delete('img_%s' % image_code_id)
        except RedisError as e:
            logger.error(e)

        # 将从redis中取出的图片验证码转成str格式，因为redis中存储的时候是bytes格式
        image_code_server = image_code_server.decode()

        # 比较用户输入的图片验证码与服务器存储的真实图片验证码
        if text.lower() != image_code_server.lower():
            raise serializers.ValidationError("图片验证码错误")

        # 如果在比较后进行删除，则当比较一直失败的时候，验证码无法删除

        # 通过debugger模式，获取上下文对象中的mobile
        mobile = self.context['view'].kwargs['mobile']
        # 根据mobile查询redis中的短信发送标志
        send_flag = redis_conn.get("send_flag_%s" % mobile)
        # 判断短信发送标志是否为空(销毁)
        if send_flag:
            raise serializers.ValidationError('发送短信验证码过于频繁')

        return attrs
